/*================================================================
 *   Copyright (C) 2021 All rights reserved.
 *   
 *   文件名称：x_config.cc
 *   创 建 者：汉森伯逸
 *   创建日期：2021年04月27日
 *   描    述：
 *
 *================================================================*/

#include <list>

#include "config.h"

namespace hsby{

ConfigVarBase::Ptr Config::LookupBase(const std::string& name){
    RWMutexType::ReadLockGuardType lock(GetMutex());
    auto it = GetDatas().find(name);
    return it == GetDatas().end() ? nullptr : it->second;
}

static void ListYaml(const std::string& prefix,
                     const YAML::Node& node,
                     std::list<std::pair<std::string, const YAML::Node> >& output){
    if (prefix.find_first_not_of("abcdefghijklmnopqrstuvwxyz.1234567890_") != std::string::npos){
        return ;
    }
    output.push_back(std::make_pair(prefix, node));
    if (node.IsMap()){
        for(auto it = node.begin();
               it != node.end();++it){
            ListYaml(prefix.empty()? it->first.Scalar() : prefix+"."+it->first.Scalar(), it->second, output);
        }
    }
}

void Config::LoadFromYaml(const YAML::Node &root) {
    std::list<std::pair<std::string, const YAML::Node> > all_nodes;
    ListYaml("", root, all_nodes);

    for(auto& it : all_nodes){
        std::string key = it.first;
        if (key.empty()) continue;

        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
        ConfigVarBase::Ptr var = LookupBase(key);
        if (var){
            if (it.second.IsScalar()){
                var->FromString(it.second.Scalar());
            }else{
                std::stringstream ss;
                ss << it.second;
                var->FromString(ss.str());
            }
        }
    }

}

void Config::Visit(std::function<void(ConfigVarBase::Ptr)> cb) {
    RWMutexType::ReadLockGuardType lock(GetMutex());
    ConfigVarMap& m = GetDatas();
    for(auto& it : m) {
        cb(it.second);
    }
}
}
